using System.ComponentModel.DataAnnotations;
using Stateless;

namespace Core.Db.Models;

public enum OrderStateEnum
{
    /// <summary>
    /// 订单已生成
    /// </summary>
    Pending,

    /// <summary>
    /// 支付处理成功
    /// </summary>
    Processing,

    /// <summary>
    /// 交易成功
    /// </summary>
    Completed,

    /// <summary>
    /// 交易失败
    /// </summary>
    Declined,

    /// <summary>
    /// 订单取消
    /// </summary>
    Cancelled,

    /// <summary>
    /// 已退款
    /// </summary>
    Refund,
}

public enum OrderStateTriggerEnum
{
    /// <summary>
    /// 支付
    /// </summary>
    PlaceOrder,

    /// <summary>
    /// 支付成功
    /// </summary>
    Approve,

    /// <summary>
    /// 支付失败
    /// </summary>
    Reject,

    /// <summary>
    /// 取消
    /// </summary>
    Cancel,

    /// <summary>
    /// 退货
    /// </summary>
    Return,
}

public class Order
{
    public Order()
    {
        StateMachineInit();
    }

    [Key] public Guid Id { get; set; }
    public string UserId { get; set; }
    public ApplicationUser User { get; set; }
    public ICollection<LineItem> OrderItems { get; set; }
    public OrderStateEnum State { get; set; }
    public DateTime CreateDateUTC { get; set; }
    public string TransactionMetadata { get; set; }
    private StateMachine<OrderStateEnum, OrderStateTriggerEnum> _stateMachine;

    private void StateMachineInit()
    {
        _stateMachine = new StateMachine<OrderStateEnum, OrderStateTriggerEnum>(OrderStateEnum.Pending);
        //传入第一个 Pending 状态
        _stateMachine.Configure(OrderStateEnum.Pending)
            .Permit(OrderStateTriggerEnum.PlaceOrder, OrderStateEnum.Processing)
            .Permit(OrderStateTriggerEnum.Cancel, OrderStateEnum.Cancelled);

        _stateMachine.Configure(OrderStateEnum.Processing)
            .Permit(OrderStateTriggerEnum.Approve, OrderStateEnum.Completed)
            .Permit(OrderStateTriggerEnum.Reject, OrderStateEnum.Declined);

        _stateMachine.Configure(OrderStateEnum.Declined)
            .Permit(OrderStateTriggerEnum.PlaceOrder, OrderStateEnum.Processing);

        _stateMachine.Configure(OrderStateEnum.Completed)
            .Permit(OrderStateTriggerEnum.Return, OrderStateEnum.Refund);
    }
}